#ifndef _ARRAYT
#define _ARRAYT

#include <iostream>
using namespace std;


#define N 50

template<class T>
class ArrayT
{
public:
	ArrayT(int size = N);
	~ArrayT();
	ArrayT(const ArrayT<T>& a);

	T& operator [] (int pos) { return ptr[pos]; }
	const T& operator [] (int pos) const { return ptr[pos]; }
	operator T* () { return ptr; }
	operator const T* () const { return ptr; }

	void PushRear(T val);
	void PushPos(T val, int pos);
	T deletePos(int pos);

	int GetSize() const { return size; }
	int GetCnt() const { return cnt; }

	template<class T>
	friend ostream& operator << (ostream& out, const ArrayT<T>& a);

private:
	int size;
	int cnt;
	T* ptr;
	void double_increase();
};

template<class T>
ArrayT<T>::ArrayT(int size)
	:size(size),cnt(size)
{
	ptr = new T[size];
}

template<class T>
ArrayT<T>::~ArrayT()
{
	delete[] ptr;
}

template<class T>
ArrayT<T>::ArrayT(const ArrayT<T>& a)
{
	size = a.size;
	cnt = a.cnt;
	ptr = new T[size];
	for (int i = 0; i < cnt; i++)
	{
		ptr[i] = a.ptr[i];
	}

}

template<class T>
void ArrayT<T>::PushRear(T val)
{
	if (cnt == size) double_increase();
	ptr[cnt++] = val;
}

template<class T>
void ArrayT<T>::PushPos(T val, int pos)
{
	if (cnt == size) double_increase();
	for (int i = cnt; i > pos; i--)
	{
		ptr[i] = ptr[i - 1];
	}
	cnt++;
	ptr[pos] = val;
}

template<class T>
T ArrayT<T>::deletePos(int pos)
{
	T temp = ptr[pos];
	for (int i = pos; i < cnt; i++)
	{
		ptr[i] = ptr[i + 1];
	}
	cnt--;
	return temp;
}

template<class T>
void ArrayT<T>::double_increase()
{
	T* temp;
	size *= 2;
	temp = new T[size];

	for (int i = 0; i < cnt; i++)
	{
		temp[i] = ptr[i];
	}

	delete[] ptr;
	ptr = temp;
}


template<class T>
ostream& operator << (ostream& out, const ArrayT<T>& a)
{
	for (int i = 0; i < a.cnt; i++)
	{
		out << a[i] << "  ";
	}
	out << endl;

	return out;
}


#endif // !_ARRAYT



